package cn.xuan.zp.service.shiro;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.xuan.zp.db.domain.Resource;
import cn.xuan.zp.db.domain.Role;
import cn.xuan.zp.db.domain.User;
import cn.xuan.zp.db.mapper.RoleMapper;
import cn.xuan.zp.service.resource.IResourceService;
import cn.xuan.zp.service.role.IRoleService;
import cn.xuan.zp.service.user.IUserService;

@Service
public class ShiroReam extends AuthorizingRealm{
	
    private static final Logger LOGGER = LoggerFactory.getLogger(ShiroReam.class);
    @Autowired
    private IUserService userService;
    @Autowired
    private IRoleService roleService;
    @Autowired
    private IResourceService resourceService;

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        try {
			User user = userService.getByPrimaryKey(userId);
			List<Role> roles = new ArrayList<>();
			List<Resource> resources = new ArrayList<>();
			if(user != null) {
				roles = roleService.queryRoleByUser(user);				
			}
			if(roles != null) {
				for (Role role : roles) {
					info.addRole(role.getRoleKey());
				}
				resources = resourceService.queryResourceByRoles(roles);
				if(resources != null && resources.size()>0) {
	                Set<String> permissionSet = new HashSet<String>();
					for (Resource resource : resources) {						
						permissionSet.addAll(Arrays.asList(resource.getPermissions().split(",")));
					}
					info.addStringPermissions(permissionSet);
				}
			}

			info.addStringPermission("admin");
		} catch (Exception e) {
			LOGGER.error("ShiroReam.doGetAuthorizationInfo",e);
		}
		return info;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		// 获取用户的输入的账号.
        String loginname = (String) token.getPrincipal();
        User user = null;
        List<User> lst = new ArrayList<>();
		try {
			lst = userService.queryUserByLoginName(loginname);
		} catch (Exception e) {
			LOGGER.error("ShiroReam.doGetAuthenticationInfo",e);
		}
    	if(lst != null && lst.size() > 0) {
    		user = lst.get(lst.size()-1);
    		if("99".equals(user.getStatus())) { // lock
                throw new LockedAccountException("帐号已被锁定，禁止登录！");
    		}
    		if("0".equals(user.getStatus())) { // unaviable
                throw new DisabledAccountException("帐号被禁用请联系管理员！");
    		}
    	}else {
            throw new UnknownAccountException("账号不存在！");
    	}
    	return new SimpleAuthenticationInfo(user.getId(), user.getPwd(), ByteSource.Util.bytes(loginname),
                getName());
	}

}
